//
//  DeferTest.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/4/30.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import UIKit

class DeferTestVC : UIViewController {
    
    /* defer代码块调用规则
    *1、defer所在的func或scope必须执行到defer才会触发
    *2、所在func或scope结束时执行时调用defer代码块
    *3、多个defer时压栈，先进后出
    *4、嵌套中的defer满足条件1、2、3
    *5、continue 或者 break 都不会妨碍 defer 的执行
    *6、defer代码块不一定总是最后执行，比如所在func或scope中有异步操作时(testFunc6)，但总是在func或scope最后一行执行结束之后执行
    */
    
    override func viewDidLoad() {
//        testFunc()
        testFunc1() 
        for idx in 0...10 {
            testFunc6()
        }
    }

    /// end  defer2  defer1 defer in
    func testFunc() {
      defer{
        defer{
          print("defer in")
        }
        print("defer1")
      }
      defer{
        print("defer2")
      }
      print("end")
    }

    // handle error    finally
    func testFunc1() {
        debugPrint("-----testFunc1-----")
      do{
        defer{
          print("finally")
        }
        throw NSError()
        debugPrint("impossible")
      }catch{
        debugPrint("handle error")
      }
    }

//    用途
    func testFunc2() {
      let path = ""
      let fileDescriptor = open(path, O_EVTONLY)
      defer{
       close(fileDescriptor)
      }
      // use fileDescriptor...
      print("end")
    }

    func testFunc3() {
        let valuePointer = UnsafeMutablePointer<Any>.allocate(capacity:1)
      defer{
       valuePointer.deallocate()
      }
      // use pointer...
      print("end")
    }

    func testFunc4() {
      let lock = NSLock()
      //同下面的.lock() .unlock()
    //    objc_sync_enter(lock)
    //    defer {
    //     objc_sync_exit(lock)
    //    }
      lock.lock()
      defer{ lock.unlock() }
      // do something...
      print("end")
    }

    func testFunc5(completion: () ->Void,str:String?) {
      defer{
       completion()
      }
      guard let _ = str else { return }
      // handle success
      print("end")
    }

    override func viewWillLayoutSubviews() {
      defer{
       super.viewWillLayoutSubviews()
      }
      //主要目的是在 super 方法之前做一些准备工作
      // some preparation before super.viewWillLayoutSubviews()...
      print("end")
    }

    //
    func testFunc6() {
        debugPrint("------testFunc6------")
      defer{
        print("defer")
      }
      let queue = DispatchQueue.init(label:"uuuuuuuuuuu")
      for i in 0...2{
        queue.async{
          print("async\(i)")
        }
      }
      print("end")
    }

}
